home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr22 / byte24.zip / DBSUBS.C < prev    next >
Text File  |  1990-05-11  |  7KB  |  334 lines

  1. /* Database handling subroutines for benchmark interface
  2. **
  3. ** BYTE Magazine, Spring 1990
  4. **
  5. ** init_db: reads in db records, if file exists.
  6. ** lin_search_db: returns index with matching criteria
  7. ** sort_db: sorts on one field
  8. ** update_db: updates one field in one record
  9. ** add_entry_db: adds an entry, marks it current.
  10. ** dump_db: writes db out to a file
  11. ** free_db: frees up memory allocated by init_db
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <sys/stat.h>
  17. #include <stdlib.h>
  18. #include <io.h>
  19. #include <string.h>
  20.  
  21. #include "db.h"
  22.  
  23. char init_db(char num_records_limit, db_rec** listptr, char * dbfilename)
  24. /* looks for dbfilename. If it exists, reads in records */
  25. /* returns number of records in database */
  26.  
  27. {
  28. int i;
  29. char num_records=0;
  30. int dbfh;
  31.  
  32.     dbfh=open(dbfilename, O_BINARY|O_RDONLY);
  33.  
  34.     if(dbfh==-1)
  35.         return 0;
  36.     if( read(dbfh, &num_records, 1) <= 0){
  37.         close(dbfh);
  38.         return 0; 
  39.         }
  40.  
  41.     num_records=(num_records>num_records_limit-1)? \
  42.         num_records_limit-1:num_records;
  43.  
  44.     /* allocate the memory */
  45.  
  46.     for(i=0; i<(int)num_records; i++){
  47.        if ((*(listptr+i)=(db_rec*)malloc(sizeof(db_rec)))==NULL){
  48.             num_records=(char)i;
  49.             break;
  50.             }
  51.         }
  52.  
  53.     /* read-em in*/
  54.     for(i=0; i<(int)num_records; i++){
  55.         read(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
  56.         }
  57.  
  58.     close(dbfh);
  59.     return num_records;
  60. }
  61.  
  62. int dump_db(char num_records, db_rec** listptr, char * dbfilename)
  63. /* dumps records to file */
  64. {
  65. int i;
  66. int dbfh;
  67.  
  68.     /* open file */
  69.  
  70.     dbfh=open(dbfilename, O_TRUNC|O_WRONLY|O_BINARY|O_CREAT);
  71.  
  72.     if (dbfh==-1)
  73.          return 0;
  74.     if( write(dbfh, &num_records, 1) <= 0){
  75.         close(dbfh);
  76.         return 0; 
  77.         }
  78.  
  79.     /* write-em */
  80.  
  81.     for(i=0; i<(int)num_records; i++){
  82.         write(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
  83.         }
  84.  
  85.     close(dbfh);
  86.     return 1;
  87. }
  88.  
  89. void free_db(char num_records, db_rec** listptr)
  90. /* frees all memory allocated to records */
  91. {
  92. int i;
  93.  
  94.     for(i=0; i<(int)num_records; i++){
  95.         free(*(listptr+i));
  96.         }
  97. }
  98.  
  99. int lin_search_db(char startpos, char endpos, void** listptr,    \
  100.          int struct_offset, char crit_type_code, double crit)
  101. /* unsorted linear search. Return index of first match found, -1 on no match.
  102. ** crit=value to match. struct_offset=location of field to match.
  103. */
  104. {
  105. int i;
  106. int temp;
  107.  
  108. switch(crit_type_code){
  109.     case CHARCODE:
  110.       for(i=(int)startpos;i<=(int)endpos;i++){
  111.            if(*((char*)
  112.             ((char *)(*(listptr+i))+struct_offset))    \
  113.             ==(char)crit)
  114.             return i;
  115.            }
  116.         return -1;
  117.     case INTCODE:
  118.       for(i=(int)startpos;i<=(int)endpos;i++){
  119.            if(*((unsigned int*)    \
  120.             ((char *)(*(listptr+i))+struct_offset))    \
  121.             ==(unsigned int)crit)
  122.             return i;
  123.           }
  124.         return -1;
  125.     case FLOATCODE:
  126.       for(i=(int)startpos;i<=(int)endpos;i++){
  127.            if(*((double *)    \
  128.             ((char *)(*(listptr+i))+struct_offset))    \
  129.             ==(double)crit)
  130.             return i;
  131.           }
  132.         return -1;
  133.     case CHARPTRCODE:
  134.       temp=(int) crit;
  135.        for(i=(int)startpos;i<=(int)endpos;i++){
  136.           if(strcmp(    \
  137.             ((char *)(*(listptr+i))+struct_offset),
  138.             (char*)temp)==0)
  139.             return i;
  140.           }
  141.         return -1;
  142.     default:
  143.         return -1;
  144.     }
  145. }
  146.  
  147.  
  148. void sort_db( char num_records, void** listptr,    \
  149.     int struct_offset, char ft_code)
  150. /*
  151. ** quicksort for these structures
  152. ** adapted from Esakov-Weiss, _Data_Structures_
  153. **
  154. */
  155. {
  156.  
  157. void** left;
  158. void** right;
  159. void** el;
  160. char num_remaining;
  161.  
  162. void swap(void**, void**);
  163. int comp_fld_ptr(void**, void**, int, char);
  164.  
  165. if (num_records<=1)    return;
  166. left=listptr;
  167. right=listptr+(num_records-1);
  168. el=left;
  169.  
  170. swap (el, right);
  171. el=right;
  172.  
  173. while(left<right){
  174.     while((comp_fld_ptr(left,el,struct_offset, ft_code)<0)&&(left<right))
  175.         left++;
  176.     while((comp_fld_ptr(right,el,struct_offset,ft_code)>=0)&&(left<right))
  177.         right--;;
  178.     if(left<right){
  179.         swap(left,right);
  180.         left++;
  181.         }
  182.     }
  183. if(right==listptr){
  184.     swap(right, el);
  185.     right++;
  186.     }
  187.  
  188. num_remaining=(right-listptr);
  189. sort_db(num_remaining, listptr, struct_offset,     ft_code);
  190. sort_db(num_records-num_remaining, right, struct_offset, ft_code);
  191.  
  192. }
  193.  
  194. void swap(void** a, void** b)
  195. {
  196. void* temp;
  197.     temp=*a;
  198.     *a=*b;
  199.     *b=temp;
  200. }
  201.  
  202. int comp_fld_ptr(void** a, void** b, int s_off, char f_code)
  203. {
  204.  
  205.     switch(f_code){
  206.         case CHARCODE:
  207.             if( *((char*) ((char *)(*a)+s_off)) <
  208.                 *((char*) ((char *)(*b)+s_off)))
  209.                 return 1;
  210.             if( *((char*) ((char *)(*a)+s_off)) >
  211.                 *((char*) ((char *)(*b)+s_off)))
  212.                 return -1;
  213.             return 0;
  214.  
  215.         case INTCODE:
  216.             if( *((unsigned int*) ((char *)(*a)+s_off)) <
  217.                 *((unsigned int*) ((char *)(*b)+s_off)))
  218.                 return 1;
  219.             if( *((unsigned int*) ((char *)(*a)+s_off)) >
  220.                 *((unsigned int*) ((char *)(*b)+s_off)))
  221.                 return -1;
  222.             return 0;
  223.  
  224.         case FLOATCODE:
  225.             if( *((double*) ((char *)(*a)+s_off)) <
  226.                 *((double*) ((char *)(*b)+s_off)))
  227.                 return 1;
  228.             if( *((double*) ((char *)(*a)+s_off)) >
  229.                 *((double*) ((char *)(*b)+s_off)))
  230.                 return -1;
  231.             return 0;
  232.  
  233.         case CHARPTRCODE:
  234.             return strcmp(((char *)(*b)+s_off),    \
  235.                       ((char *)(*a)+s_off));
  236.         }
  237.     return 0;
  238. }
  239.  
  240.  
  241. void update_db(int index, void** listptr, int struct_offset,    \
  242.           char ft_code, double newvalue)
  243. /*
  244. ** updates a db entry.
  245. */
  246.  
  247. {
  248.  
  249. int temp;
  250.  
  251.     switch(ft_code){
  252.         case CHARCODE:
  253.             *((char*)    \
  254.             ((char*)(*(listptr+index))+struct_offset))=    \
  255.             (char) newvalue;
  256.             break;
  257.  
  258.         case INTCODE:
  259.             *((unsigned int*)    \
  260.             ((char*)(*(listptr+index))+struct_offset))=    \
  261.             (unsigned int) newvalue;
  262.             break;
  263.  
  264.         case FLOATCODE:
  265.             *((double *)    \
  266.             ((char*)(*(listptr+index))+struct_offset))=    \
  267.             (double) newvalue;
  268.             break;
  269.  
  270.         case CHARPTRCODE:
  271.             temp=(int) newvalue;
  272.             strcpy(
  273.             ((char*)(*(listptr+index))+struct_offset),    \
  274.             (char*) temp);
  275.            }
  276. }
  277.  
  278. char add_entry_db( char num_records_limit, char num_records,    \
  279.            db_rec** listptr, char* entryname)
  280. /* adds a db entry. Returns number of records in new db. If records in
  281. ** equals records out, you're out of room.
  282. */
  283.  
  284. {
  285. int i;
  286. int curroff;
  287.  
  288.     if(num_records==num_records_limit) return num_records;
  289.  
  290.     /* allocate the memory */
  291.     if((*(listptr+num_records)=(db_rec*)malloc(sizeof(db_rec)))==NULL)
  292.             return num_records;
  293.  
  294.     /* clear current entry */
  295.     if(num_records!=0){
  296.         curroff=lin_search_db(0, num_records-1, (void**) listptr,    \
  297.             offset_in_struc(db_rec,currflag), INTCODE, 1);
  298.         if(curroff>(-1)){
  299.             update_db(curroff,(void**) listptr,
  300.                 offset_in_struc(db_rec,currflag), INTCODE, 0);
  301.             }
  302.         }
  303.  
  304.     /* zero out new entry */
  305.     for(i=0; i<sizeof(db_rec); i++)
  306.         *(*((char**)listptr+num_records)+i)=0;
  307.  
  308.     /* make new entry current */
  309.     update_db((int)num_records,(void**) listptr,
  310.         offset_in_struc(db_rec,currflag), INTCODE, 1);
  311.  
  312.     /* give it a name */
  313.     update_db((int)num_records,(void**) listptr,
  314.         offset_in_struc(db_rec,name), CHARPTRCODE, (int)entryname);
  315.  
  316.     return num_records+1;
  317. }
  318.  
  319. void dup_rec( void** listptr, int destoff, int sourceoff)
  320. /*
  321. ** duplicates records.
  322. */
  323.  
  324. {
  325. int i;
  326.  
  327.     for(i=0; i<sizeof(db_rec); i++){
  328.         *(*((char**)listptr+destoff)+i)=    \
  329.         *(*((char**)listptr+sourceoff)+i);
  330.         }
  331.  
  332. }
  333.  
  334.